<template>
	<Drawer :visible="visible" side="left" @close="handleClose">
		<!-- 内容区 -->
		<template #content>
			<div class="flex flex-col mx-auto w-full h-full">
				<h2 class="font-playball font-medium text-black text-4xl leading-tight">Cart</h2>
				<div class="divide-y divide-gray-200">
					<div v-for="(p, idx) in products" :key="p.id" class="flex py-6">
						<div class="flex flex-row gap-4">
							<div class="w-24 h-24 rounded-lg bg-neutral-100 overflow-hidden flex items-center justify-center p-2">
								<img :src="p.image" />
							</div>
							<div class="flex flex-col items-start justify-start min-w-0">
								<div class="font-medium text-base leading-tight">{{ p.name }}</div>
								<div class="text-neutral-400 text-sm mt-1">${{ p.price.toFixed(2) }}</div>
							</div>
						</div>
						<div class="flex flex-col items-end justify-between">
							<div class="text-right font-medium text-base min-w-[60px]">${{ (p.price * p.qty).toFixed(2) }}</div>
							<div class="flex items-center gap-2 bg-gray-100 rounded-full px-2 py-1">
								<button @click="handleSubQuantity(idx)" class="w-6 h-6 rounded-full flex items-center justify-center text-lg font-bold">-</button>
								<input
									min="0"
									:value="p.qty"
									@input="handleInputQuantity(idx, $event)"
									class="w-10 text-center bg-transparent outline-none"
								/>
								<button @click="handleAddQuantity(idx)" class="w-6 h-6 rounded-full flex items-center justify-center text-lg font-bold">+</button>
							</div>
						</div>
					</div>
				</div>
				<div class="py-4 text-black ">
					<div class=" text-3xl mb-1 font-playball">You might also like</div>
					<p class="text-xs border-b font-poppins border-neutral-300 pb-3 mb-6">
						Check out product recommendations tailored to you.
					</p>
					<transition
						enter-active-class="transition-all duration-500 ease-out"
						enter-from-class="opacity-0 translate-y-10"
						enter-to-class="opacity-100 translate-y-0"
						leave-active-class="transition-all duration-300 ease-in"
						leave-from-class="opacity-100 translate-y-0"
						leave-to-class="opacity-0 translate-y-10"
						appear
					>
						<div v-if="visibleRecommend" class="space-y-4">
							<transition
								v-for="(product, index) in recommendProducts"
								:key="product.id"
								:enter-active-class="'transition-all duration-500 ease-out'"
								:enter-from-class="'opacity-0 translate-y-10'"
								:enter-to-class="'opacity-100 translate-y-0'"
								:leave-active-class="'transition-all duration-300 ease-in'"
								:leave-from-class="'opacity-100 translate-y-0'"
								:leave-to-class="'opacity-0 translate-y-10'"
								:style="{ transitionDelay: `${index * 200}ms` }"
								appear
							>
								<div class="flex items-center gap-4 rounded-lg">
									<div class="w-16 h-16 rounded-lg bg-neutral-100 overflow-hidden flex items-center justify-center p-2">
										<img :src="product.image" />
									</div>
									<div class="flex-1 min-w-0">
										<div class="font-medium text-base leading-tight">{{ product.name }}</div>
										<div class="text-gray-400 text-xs mt-3">${{ product.price.toFixed(2) }}</div>
									</div>
									<button class="rounded-3xl bg-rose-600 px-3 py-2 flex items-center text-white justify-center gap-1 text-lg font-bold">
										 + <icon-park-mall-bag theme="outline" size="20" />
									</button>
								</div>
							</transition>
						</div>
					</transition>
				</div>
			</div>
		</template>
		<!-- 底部区 -->
		<template #footer>
			<div class="pt-6 border-t border-gray-200 bg-white">
				<div class="mb-4">
					<div class="mb-2 font-medium">
						Buy with ${{ leftToFree }} more to get free shipping!
					</div>
					<div class="w-full h-4 rounded-full bg-gray-200 overflow-hidden">
						<div
							class="h-full rounded-full"
							:style="{
								width: (progress * 100) + '%',
								background: 'linear-gradient(90deg, #111 0%, #3a5d1b 80%, #bdbdbd 100%)',
								transition: progressTransition
							}"
						></div>
					</div>
				</div>
				<div class="flex justify-between font-medium text-base mb-2">
					<span>Subtotal</span>
					<span>${{ subtotal.toFixed(2) }} USD</span>
				</div>
				<div class="flex gap-4 mt-2">
					<button @click="handleCheckout" class="flex-1 rounded-full bg-rose-600 text-white py-4 text-base font-bold shadow hover:bg-rose-700 transition tracking-widest">
						CHECKOUT
					</button>
					<button class="flex-1 rounded-full border border-rose-600 text-rose-600 py-4 text-base font-bold bg-white hover:bg-gray-50 transition tracking-widest">VIEW
						CART
					</button>
				</div>
				<div class="text-neutral-700 text-center text-xs mt-4">Tax included. Shipping calculated at checkout</div>
			</div>
		</template>
	</Drawer>
</template>

<script lang="ts">
import { defineComponent, nextTick } from 'vue';
import Drawer from '@/components/drawer/index.vue';
import { MallBag } from '@icon-park/vue-next'

export default defineComponent({
	name: 'Cart',
	components: { 
		'icon-park-mall-bag': MallBag,
		Drawer
	},
	props: {
		/*
		* 是否可见
		*/
		visible: {
			type: Boolean,
			default: false
		}
	},
	data() {
		return {
			/*
			* 是否显示推荐
			*/
			visibleRecommend: false,
			/*
			* 免费送货阈值
			*/
			freeShippingThreshold: 200,
			/*
			* 进度
			*/
			progress: 0,
			/*
			* 进度动画
			*/
			progressAnim: null as number | null,
			/*
			* 进度超时
			*/
			progressTimeout: null as ReturnType<typeof setTimeout> | null,
			/*
			* 进度过渡
			*/
			progressTransition: 'none',
			/*
			* 产品
			*/
			products: [
				{
					id: 1,
					name: 'Beard Brush Dick Johnson',
					price: 24.90,
					image: '//cdn.shopify.com/s/files/1/0698/4368/1529/files/beard-brush-WithTube.png?v=1722835665&width=240',
					qty: 1
				}
			],
			recommendProducts: [
				{
					id: 1,
					name: 'Wash Bag Faux Leather',
					price: 34.90,
					image: '//cdn.shopify.com/s/files/1/0698/4368/1529/files/DickJohnsonWashbag_300x.png?v=1722344369'
				},
				{
					id: 2,
					name: 'Beard Oil Classic',
					price: 29.90,
					image: '//cdn.shopify.com/s/files/1/0698/4368/1529/files/beard-oil-classic.png?v=1722835665'
				},
				{
					id: 3,
					name: 'Shaving Brush',
					price: 39.90,
					image: '//cdn.shopify.com/s/files/1/0698/4368/1529/files/shaving-brush.png?v=1722835665'
				},
				{
					id: 4,
					name: 'Beard Comb',
					price: 19.90,
					image: '//cdn.shopify.com/s/files/1/0698/4368/1529/files/beard-comb.png?v=1722835665'
				},
				{
					id: 5,
					name: 'Beard Balm',
					price: 24.90,
					image: '//cdn.shopify.com/s/files/1/0698/4368/1529/files/beard-balm.png?v=1722835665'
				}
			],
		};
	},
	emits: ['close'],
	computed: {
		/*
		* 子总价
		*/
		subtotal() {
			return this.products.reduce((sum, p) => sum + p.price * p.qty, 0);
		},
		/*
		* 剩余免费送货
		*/
		leftToFree() {
			return Math.max(0, this.freeShippingThreshold - this.subtotal).toFixed(2);
		},
		/*
		* 进度百分比
		*/
		progressPercent() {
			return Math.min(1, this.subtotal / this.freeShippingThreshold);
		}
	},
	watch: {
		subtotal() {
			this.animateProgress();
		},
		visible: {
			handler() {
				if (this.visible) {
					setTimeout(() => {
						this.visibleRecommend = true;
					}, 1000);
				}
			},
			immediate: true,
			deep: true
		}
	},
	mounted() {
		this.animateProgress();
	},
	beforeUnmount() {
		if (this.progressAnim) {
			cancelAnimationFrame(this.progressAnim);
		}
		if (this.progressTimeout) {
			clearTimeout(this.progressTimeout);
		}
	},
	methods: {
		/*
		* 输入数量
		*/
		handleInputQuantity(idx: number, e: Event) {
			const target = e.target as HTMLInputElement;
			const qty = Math.max(1, Number(target.value));
			this.products[idx].qty = qty;
		},
		/*
		* 添加数量
		*/
		handleAddQuantity(idx: number) {
			this.products[idx].qty++;
		},
		/*
		* 减少数量
		*/
		handleSubQuantity(idx: number) {
			if (this.products[idx].qty > 1) this.products[idx].qty--;
		},
		/*
		* 关闭
		*/
		handleClose() {
			this.$emit('close');
			this.visibleRecommend = false;
		},
		/*
		* 动画进度
		*/
		animateProgress() {
			if (this.progressAnim) {
				cancelAnimationFrame(this.progressAnim);
			}
			if (this.progressTimeout) {
				clearTimeout(this.progressTimeout);
			}
			this.progressTransition = 'none';
			this.progress = 0;
			const end = this.progressPercent;
			const duration = 500;
			requestAnimationFrame(() => {
				requestAnimationFrame(() => {
					this.progressTimeout = setTimeout(() => {
						this.progressTransition = 'width 0.5s cubic-bezier(0.4, 0, 0.2, 1)';
						const startTime = performance.now();
						const animate = (now: number) => {
							const t = Math.min(1, (now - startTime) / duration);
							this.progress = end * t;
							if (t < 1) {
								this.progressAnim = requestAnimationFrame(animate);
							} else {
								this.progress = end;
							}
						};
						this.progressAnim = requestAnimationFrame(animate);
					}, 100);
				});
			});
		},
		handleCheckout() {
			console.log('handleCheckout');
			this.$signin?.show();
		}
	}
});
</script>